package cn.fanyamin.util;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;


public class CalendarUtils {

    public final static int MS_OF_HOUR = 60 * 60 * 1000;
    
    public final static int MS_OF_DAY = 7 * 24 * 60 * 60 * 1000;
    
    public final static int HOUR_OF_DAY = 24;
    
    public final static int DAY_OF_WEEK = 7;
    
    public final static int HOUR_OF_WEEK = 7 * 24;
    
    public static Date getMaxDateOfDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 0);

        return cal.getTime();
    }

    /**
     * DOCUMENT ME!
     *
     * @param date DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static Date getMinDateOfWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        cal.set(Calendar.DAY_OF_WEEK, cal.getActualMinimum(Calendar.DAY_OF_WEEK));
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        return cal.getTime();
    }

    /**
     * DOCUMENT ME!
     *
     * @param date DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static Date getMaxDateOfWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 0);

        return cal.getTime();
    }

    /**
     * DOCUMENT ME!
     *
     * @param date DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static Date getMinDateOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        return cal.getTime();
    }

    /**
     * DOCUMENT ME!
     *
     * @param date DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static Date getMaxDateOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 0);

        return cal.getTime();
    }

    /**
     * DOCUMENT ME!
     *
     * @param year DOCUMENT ME!
     * @param month DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static Date getMinDateOfMonth(int year, int month) {
        GregorianCalendar cal = new GregorianCalendar(year, month, 1);
        cal.set(GregorianCalendar.YEAR, year);
        cal.set(GregorianCalendar.MONTH, month);
        cal.set(GregorianCalendar.DAY_OF_MONTH, cal.getActualMinimum(GregorianCalendar.DAY_OF_MONTH));
        cal.set(GregorianCalendar.HOUR_OF_DAY, 0);
        cal.set(GregorianCalendar.MINUTE, 0);
        cal.set(GregorianCalendar.SECOND, 0);
        cal.set(GregorianCalendar.MILLISECOND, 0);

        return cal.getTime();
    }

    /**
     * DOCUMENT ME!
     *
     * @param year DOCUMENT ME!
     * @param month DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static Date getMaxDateOfMonth(int year, int month) {
        GregorianCalendar cal = new GregorianCalendar(year, month, 1);
        cal.set(GregorianCalendar.YEAR, year);
        cal.set(GregorianCalendar.MONTH, month);
        cal.set(GregorianCalendar.DAY_OF_MONTH, cal.getActualMaximum(GregorianCalendar.DAY_OF_MONTH));
        cal.set(GregorianCalendar.HOUR_OF_DAY, 23);
        cal.set(GregorianCalendar.MINUTE, 59);
        cal.set(GregorianCalendar.SECOND, 59);
        cal.set(GregorianCalendar.MILLISECOND, 0);

        return cal.getTime();
    }

    public static int getCalenderField(Date date, int field) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);

        return gc.get(field);
    }
    
    public static int getMaxDayOfMonth(Date date) {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(date);

        return gc.getActualMaximum(Calendar.DAY_OF_MONTH);
    }
    
    public static Date getMinDateOfDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        return cal.getTime();
    }
    
    public static List<Date> buildWeeklyList(Date date) {
        List<Date> list = new ArrayList<Date>(24*7);
        Date minDate = getMinDateOfWeek(date);
        for (int i = 0; i < HOUR_OF_WEEK; i++) {
            list.add(new Date(minDate.getTime()+ i * MS_OF_HOUR));
        }    
        return list;
    }
    
    public static List<Date> buildMonthlyList(Date date) {
        int days = getMaxDayOfMonth(date);
        List<Date> list = new ArrayList<Date>(days);
        Date minDate = getMinDateOfMonth(date);
        for (int i = 0; i < days; i++) {
            list.add(new Date(minDate.getTime()+ i * MS_OF_DAY));
        }
        return list;
    }
    

    public static List<Date> buildDailyList(Date date) {
        List<Date> list = new ArrayList<Date>(HOUR_OF_DAY);
        Date minDate = getMinDateOfDay(date);
        for (int i = 0; i < HOUR_OF_DAY; i++) {
            list.add(new Date(minDate.getTime() + i * MS_OF_HOUR));
        }

        return list;
    }
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}
